Skip to content

RecipeMarketplace.Category.merge: copy unmatched source children#7511

Open
natedanner wants to merge 2 commits intomainfrom
nate/marketplace-merge-no-source-aliasing
Open

RecipeMarketplace.Category.merge: copy unmatched source children#7511
natedanner wants to merge 2 commits intomainfrom
nate/marketplace-merge-no-source-aliasing

Conversation

@natedanner
Copy link
Copy Markdown
Contributor

@natedanner natedanner commented Apr 28, 2026

When Category.merge finds no name match for a source child, it adopts that child by reference (categories.add(subCategory)). Later merges that name-match into the adopted child then mutate the original source's recipes and categories. Most upstream usage hides this — RecipeMarketplace.install(BundleReader) uses a throwaway source — but consumers that cache and reuse a RecipeMarketplace as a merge source see concurrent ConcurrentModificationException / ArrayIndexOutOfBoundsException from the shared ArrayLists, and silent state drift across sequential merges.

This PR allocates a fresh Category on the receiver and recurses to copy contents instead. The recipes loop was already safe — recipe.withMarketplace(this) returns a new instance.

RecipeMarketplaceMergeTest adds two tests pinning the invariant; both fail on parent, pass with the fix. The existing merge tests in RecipeMarketplaceReaderTest only exercise the name-match path and pass unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

1 participant